﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QuickGraph;

namespace EpidemicSimulator.states
{
    public abstract class State
    {
        protected bool changingState = false;
        long stateChangeEndTime = 0;
        public int maxContacsPerStep { get; set; }
        public int minContacsPerStep { get; set; }

        public SocialNetworkNode node { get; set; }

        public static State getStateInstance(String stateClass)
        {
            Type type = Type.GetType(stateClass, true);
            object newInstance = Activator.CreateInstance(type);
            return newInstance as State;
        }

        public DiseaseModelNode stateNode { get; set; }
        public AdjacencyGraph<DiseaseModelNode, DiseaseModelEdge> diseaseModelGraph { get; set; }

        public void update(long simTime)
        {
            if (changingState && simTime == stateChangeEndTime)
            {
                node.state = node.newState;
                changingState = false;
            }
        }

        public override string ToString()
        {
            if(stateNode!=null) return this.stateNode.stateName;
            return base.ToString();
        }

        protected void changeState(State newState, long simTime, long changeDelay) {
            if (!changingState)
            {
                node.newState = newState;
                stateChangeEndTime = simTime + changeDelay;
                changingState = true;
            }
        }

        public void changeState(string newStateName)
        {
            foreach (DiseaseModelNode diseaseState in node.state.diseaseModelGraph.Vertices)
            {
                if (diseaseState.stateName == newStateName)
                {
                    node.newState = State.getStateInstance(diseaseState.stateClass);
                    node.newState.diseaseModelGraph = node.state.diseaseModelGraph;
                    node.newState.node = node;
                    node.newState.stateNode = diseaseState;
                    changingState = false;
                    return;
                }
            }
            
        }

        public abstract void stateAction(long simTime);
        public abstract void infect(SocialNetworkNode infectingNode, long simTime);
    }
}
